﻿// ***********************************************************************
// Apache 2.0 License
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY 
// IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR 
// PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing
// permissions and limitations under the License.
// ***********************************************************************
// Assembly  : ContractMeow.Models
// File      : FileAttachmentModel.cs
//
// ***********************************************************************
using ContractMeow.Api.Dtos.Attachment;
using ContractMeow.Models.Helpers;
using System;

namespace ContractMeow.Models.Attachments
{
	public class FileAttachmentModel : AttachmentModel, IFileAttachmentModel
	{
		public FileAttachmentModel()
		{
			throw new NotImplementedException("FileAttachmentModel has a public constructor for weird technical reasons, it should not be used.");
		}

		internal FileAttachmentModel(IFileAttachment apiAttachment)
			: base(apiAttachment)
		{
			Size = apiAttachment.Size;
			DownloadUrl = apiAttachment.DownloadUrl;
			ThumbnailUrl = apiAttachment.ThumbnailUrl;
			LargeIconUrl = apiAttachment.LargeIconUrl;
			OverlayUrl = apiAttachment.OverlayUrl;
			OwnerId = apiAttachment.OwnerId;
			OwnerType = apiAttachment.OwnerType;
			Path = apiAttachment.Path;
			SetPreviewUrl(apiAttachment.PreviewUrl);
			SmallIconUrl = apiAttachment.SmallIconUrl;
			StreamingUrl = apiAttachment.StreamingUrl;
			Uuid = apiAttachment.Uuid;
			YId = apiAttachment.YId;

			SetFileType();
		}

		private void SetPreviewUrl(Uri previewUrl)
		{
			PreviewUrl = previewUrl;
			if (previewUrl == null)
				return;

			var uriBuilder = new UriBuilder(previewUrl);
			if (string.IsNullOrEmpty(uriBuilder.Query))
			{
				uriBuilder.Query = "downloadable=false&editable=false";
			}

			PreviewUrl = uriBuilder.Uri;
		}


		private void SetFileType()
		{
			var extension = GetExtension();

			FileType = AttachmentHelper.GetFileTypeByExtension(extension);
		}

		public string GetExtension()
		{
			string extension;

			try {
				var lastDotIndex = Name.LastIndexOf('.');
				extension = lastDotIndex > 0 ? Name.Substring(lastDotIndex).ToLower() : string.Empty;
			}
			catch (Exception)
			{
				extension = string.Empty;
			}

			return extension;
		}

		#region IFileAttachmentModel
		private Uri _downloadUrl;
		public Uri DownloadUrl
		{
			get { return _downloadUrl; }
			set
			{
				_downloadUrl = value;
			}
		}

		private Uri _thumbnailUrl;
		public Uri ThumbnailUrl
		{
			get { return _thumbnailUrl; }
			set
			{
				_thumbnailUrl = value;
			}
		}

		private Uri _largeIconUrl;
		public Uri LargeIconUrl
		{
			get { return _largeIconUrl; }
			set
			{
				_largeIconUrl = value;
			}
		}

		private Uri _overlayUrl;
		public Uri OverlayUrl
		{
			get { return _overlayUrl; }
			set
			{
				_overlayUrl = value;
			}
		}

		private Int64 _ownerId;
		public Int64 OwnerId
		{
			get { return _ownerId; }
			set
			{
				_ownerId = value;
			}
		}

		private String _ownerType;
		public String OwnerType
		{
			get { return _ownerType; }
			set
			{
				_ownerType = value;
			}
		}

		private String _path;
		public String Path
		{
			get { return _path; }
			set
			{
				_path = value;
			}
		}

		public bool IsCacheable
		{
			get { return true; }
		}

		private Uri _previewUrl;
		public Uri PreviewUrl
		{
			get { return _previewUrl; }
			set
			{
				_previewUrl = value;
			}
		}

		private Uri _smallIconUrl;
		public Uri SmallIconUrl
		{
			get { return _smallIconUrl; }
			set
			{
				_smallIconUrl = value;
			}
		}

		private Uri _streamingUrl;
		public Uri StreamingUrl
		{
			get { return _streamingUrl; }
			set
			{
				_streamingUrl = value;
			}
		}

		private String _uuid;
		public String Uuid
		{
			get { return _uuid; }
			set
			{
				_uuid = value;
			}
		}

		private Int64 _yId;
		public Int64 YId
		{
			get { return _yId; }
			set
			{
				_yId = value;
			}
		}

		private FileType _fileType;
		public FileType FileType
		{
			get { return _fileType; }
			private set
			{
				if (_fileType != value)
				{
					_fileType = value;
				}
			}
		}

		#endregion

		/// <summary>
		/// Performs an implicit conversion from <see cref="AttachmentModel" /> to <see cref="Attachment" />.
		/// </summary>
		/// <param name="attachment">The apiAttachment.</param>
		/// <returns>The result of the conversion.</returns>
		public static implicit operator FileAttachment(FileAttachmentModel attachment)
		{
			return new FileAttachment
				{
					Id = attachment.Id,
					CreatedAt = attachment.CreatedAt,
					Description = attachment.Description,
					DownloadUrl = attachment.DownloadUrl,
					GroupId = attachment.GroupId,
					Size = attachment.Size,
					Url = attachment.Url == null ? "" : attachment.Url.ToString(),
					WebUrl = attachment.WebUrl == null ? "" : attachment.WebUrl.ToString(),
				};
		}

		/// <summary>
		/// Performs an implicit conversion from <see cref="FileAttachmentModel" /> to <see cref="ImageAttachment" />.
		/// </summary>
		/// <param name="attachment">The attachment.</param>
		/// <returns>The result of the conversion.</returns>
		public static implicit operator ImageAttachment(FileAttachmentModel attachment)
		{
			return new ImageAttachment
				{
					Id = attachment.Id,
					CreatedAt = attachment.CreatedAt,
					Description = attachment.Description,
					DownloadUrl = attachment.DownloadUrl,
					GroupId = attachment.GroupId,
					Size = attachment.Size,
					Url = attachment.Url == null ? "" : attachment.Url.ToString(),
					WebUrl = attachment.WebUrl == null ? "" : attachment.WebUrl.ToString(),
				};
		}

		/// <summary>
		/// Performs an explicit conversion from <see cref="Attachment" /> to <see cref="AttachmentModel" />.
		/// </summary>
		/// <param name="attachment">The apiAttachment.</param>
		/// <returns>The result of the conversion.</returns>
		public static explicit operator FileAttachmentModel(FileAttachment attachment)
		{
			return new FileAttachmentModel(attachment);
		}

		public static explicit operator FileAttachmentModel(ImageAttachment attachment)
		{
			return new FileAttachmentModel(attachment);
		}

		public static FileAttachmentModel FromIAttachment(IFileAttachment attachment)
		{
			return new FileAttachmentModel(attachment);
		}

		public bool CanPreview
		{
			get { return FileType == FileType.Image || (PreviewUrl != null && (FileType == FileType.Pdf || FileType == FileType.Word || FileType == FileType.PowerPoint)); }
		}

	}
}